;=================================================================================
;=========== SOME FUNCTION FOR VECTEURS 3D
;=================================================================================
Structure iVECTOR3
  x.f
  y.f
  z.f
EndStructure

Macro VECTOR3_(dest,v1,v2,v3)
  dest\x = v1
  dest\y = v2
  dest\z = v3
EndMacro

Procedure Vec3_Zero(*res.iVECTOR3)
  *res\x = 0
  *res\y = 0
  *res\z = 0
EndProcedure

Procedure.l Vec3_Equals(*vec1.iVECTOR3, *vec2.iVECTOR3)
  *vec1\x = *vec2\x
  *vec1\y = *vec2\y
  *vec1\z = *vec2\z
EndProcedure

Procedure.l Vec3_isEquals(*vec1.iVECTOR3, *vec2.iVECTOR3)
  If (*vec1\x = *vec2\x) And (*vec1\y = *vec2\y) And (*vec1\z = *vec2\z)
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure Vec3_Add(*res.iVECTOR3, *vec1.iVECTOR3, *vec2.iVECTOR3)
  *res\x = *vec1\x + *vec2\x
  *res\y = *vec1\y + *vec2\y
  *res\z = *vec1\z + *vec2\z
EndProcedure

Procedure Vec3_AddF(*res.iVECTOR3, *vec1.iVECTOR3, x.f, y.f, z.f)
  *res\x = *vec1\x + x
  *res\y = *vec1\y + y
  *res\z = *vec1\z + z
EndProcedure

Procedure Vec3_Sub(*res.iVECTOR3, *vec1.iVECTOR3, *vec2.iVECTOR3)
  *res\x = *vec1\x - *vec2\x
  *res\y = *vec1\y - *vec2\y
  *res\z = *vec1\z - *vec2\z
EndProcedure

Procedure Vec3_Mul(*res.iVECTOR3, *vec1.iVECTOR3, *vec2.iVECTOR3)
  *res\x = *vec1\x * *vec2\x
  *res\y = *vec1\y * *vec2\y
  *res\z = *vec1\z * *vec2\z
EndProcedure

Procedure Vec3_Div(*res.iVECTOR3, *vec1.iVECTOR3, *vec2.iVECTOR3)
  *res\x = *vec1\x / *vec2\x
  *res\y = *vec1\y / *vec2\y
  *res\z = *vec1\z / *vec2\z
EndProcedure

Procedure Vec3_MulF(*res.iVECTOR3, *vec1.iVECTOR3, length.f)
  *res\x = *vec1\x * length
  *res\y = *vec1\y * length
  *res\z = *vec1\z * length
EndProcedure

Procedure Vec3_CrossProduct(*res.iVECTOR3, *vec1.iVECTOR3, *vec2.iVECTOR3)
  *res\x = (*vec1\y * *vec2\z) - (*vec1\z * *vec2\y)
  *res\y = (*vec1\z * *vec2\x) - (*vec1\x * *vec2\z)
  *res\z = (*vec1\x * *vec2\y) - (*vec1\y * *vec2\x)
EndProcedure

Procedure.f Vec3_DotProduct(*vec1.iVECTOR3, *vec2.iVECTOR3)
  Protected l.f
  l = *vec1\x * *vec2\x + *vec1\y * *vec2\y + *vec1\z * *vec2\z
  ProcedureReturn l
EndProcedure

Procedure.f Vec3_GetLength(*vec1.iVECTOR3)
  Protected res.f
  
    res = (*vec1\x * *vec1\x) + (*vec1\y * *vec1\y) + (*vec1\z * *vec1\z)
    ProcedureReturn Sqr(res)
EndProcedure

Procedure.f Vec3_GetDistanceFrom(*vec1.iVECTOR3, *vec2.iVECTOR3)
    Protected tmp.iVECTOR3
    tmp\x = *vec1\x - *vec2\x
    tmp\y = *vec1\y - *vec2\y
    tmp\z = *vec1\z - *vec2\z
    res.f = Vec3_GetLength( @tmp )
    ProcedureReturn res
EndProcedure



 ; SELF

Procedure Vec3_Normalize(*vec1.iVECTOR3)
  Protected length.f
    length = Sqr( (*vec1\x * *vec1\x) + (*vec1\y * *vec1\y) + (*vec1\z * *vec1\z) )
    If length=0 : ProcedureReturn 0 : EndIf
    *vec1\x = *vec1\x / length
    *vec1\y = *vec1\y / length
    *vec1\z = *vec1\z / length
EndProcedure
 
Procedure Vec3_SetLength(*vec1.iVECTOR3, newLength.f)
    Vec3_Normalize(*vec1)
    Vec3_MulF(*vec1, *vec1, newLength)
EndProcedure

Procedure Vec3_Invert(*vec1.iVECTOR3)
    *vec1\x = *vec1\x * -1.0
    *vec1\y = *vec1\y * -1.0
    *vec1\z = *vec1\z * -1.0
EndProcedure


Procedure Vec3_RotateXZ(angle.f, *vec.iVECTOR3, *center.iVECTOR3)
  Protected cs.f, sn.f
  
   cs = Cos(angle)
   sn = Sin(angle)
   *vec\x = *vec\x - *center\x
   *vec\z = *vec\z - *center\z
   *vec\x = ( *vec\x * cs - *vec\z*sn ) 
   *vec\z = ( *vec\x * sn + *vec\z*cs ) 
   *vec\x = *vec\x + *center\x
   *vec\z = *vec\z + *center\z
EndProcedure

Procedure Vec3_RotateXY(angle.f, *vec.iVECTOR3, *center.iVECTOR3)
  Protected cs.f, sn.f

   cs = Cos(angle)
   sn = Sin(angle)
   *vec\x = *vec\x - *center\x
   *vec\y = *vec\y - *center\y
   *vec\x = ( *vec\x * cs - *vec\y*sn ) 
   *vec\y = ( *vec\x * sn + *vec\y*cs ) 
   *vec\x = *vec\x + *center\x
   *vec\y = *vec\y + *center\y
EndProcedure

Procedure Vec3_RotateYZ(angle.f, *vec.iVECTOR3, *center.iVECTOR3)
  Protected cs.f, sn.f

   cs = Cos(angle)
   sn = Sin(angle)
   *vec\z = *vec\z - *center\z
   *vec\y = *vec\y - *center\y
   *vec\y = ( *vec\y * cs - *vec\z*sn ) 
   *vec\z = ( *vec\y * sn + *vec\z*cs ) 
   *vec\z = *vec\z + *center\z
   *vec\y = *vec\y + *center\y
EndProcedure

Procedure Vec3_GetHorizontalAngle(*angle.iVECTOR3, *vec.iVECTOR3)
  Protected z1.f
  
			*angle\y = ATan2(*vec\x, *vec\z)

			If *angle\y < 0.0
				*angle\y = *angle\y + #PI2
			EndIf
			
			If *angle\y >= #PI2
				*angle\y = *angle\y - #PI2
      EndIf
      
			z1 = Sqr( *vec\x* *vec\x + *vec\z * *vec\z)

			*angle\x = atan2(z1, *vec\y) * RADTODEG64 - 90.0

			If *angle\x < 0.0
				*angle\x = *angle\x + #PI2
			EndIf
			If *angle\x >= #PI2
				*angle\x = *angle\x - #PI2
      EndIf 
EndProcedure

Procedure Vec3_RotationToDirection(*res.iVECTOR3, *vec.iVECTOR3, *forwards.iVECTOR3)
    Protected Dim pseudoMatrix.f(9)
    Protected cr.f, sr.f, cp.f, sp.f, cy.f, sy.f, srsp.f, crsp.f
  
			cr = Cos( *vec\x )
			sr = Sin( *vec\x )
			cp = Cos( *vec\y )
			sp = Sin( *vec\y )
			cy = Cos( *vec\z )
			sy = Sin( *vec\z )

			srsp = sr*sp
			crsp = cr*sp

				pseudoMatrix(0)= cp*cy
				pseudoMatrix(1)= cp*sy
				pseudoMatrix(2)= -sp
				pseudoMatrix(3)= srsp*cy-cr*sy
				pseudoMatrix(4)= srsp*sy+cr*cy
				pseudoMatrix(5)= sr*cp
				pseudoMatrix(6)= crsp*cy+sr*sy
				pseudoMatrix(7)= crsp*sy-sr*cy
				pseudoMatrix(8)= cr*cp

      *res\x = *forwards\x * pseudoMatrix(0)+ *forwards\y * pseudoMatrix(3)+ *forwards\z * pseudoMatrix(6)
			*res\y = *forwards\x * pseudoMatrix(1)+ *forwards\y * pseudoMatrix(4)+ *forwards\z * pseudoMatrix(7)
			*res\z = *forwards\x * pseudoMatrix(2)+ *forwards\y * pseudoMatrix(5)+ *forwards\z * pseudoMatrix(8)
EndProcedure	

; IDE Options = PureBasic 4.30 Beta 5 (Windows - x86)
; CursorPosition = 3
; Folding = ----